/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 */
package org.olap4j;

import org.olap4j.metadata.Property;

import java.sql.ResultSet;
import java.util.List;

/**
 * Cell returned from a {@link CellSet}.
 * 
 * @author jhyde
 * @since Aug 22, 2006
 */
public interface Cell {
	/**
	 * Returns the {@link CellSet} that this Cell belongs to.
	 * 
	 * @return CellSet, never null
	 */
	CellSet getCellSet();

	/**
	 * Returns the ordinal of this Cell.
	 * 
	 * <p>
	 * The formula is the sequence, zero-based, which the cell would be visited in a raster-scan through all of the
	 * cells of this {@link CellSet}. The ordinal of the first cell is zero, and the ordinal of the last cell is the
	 * product of the lengths of the axes, minus 1. For example, if a result has 10 columns and 20 rows, then:
	 * <ul>
	 * <li>(row 0, column 0) has ordinal 0,</li>
	 * <li>(row 0, column 1) has ordinal 1,</li>
	 * <li>(row 1, column 0) has ordinal 10,</li>
	 * <li>(row 19, column 9) has ordinal 199.</li>
	 * </ul>
	 * 
	 * @return Ordinal of this Cell
	 */
	int getOrdinal();

	/**
	 * Returns the coordinates of this Cell in its {@link CellSetAxis}.
	 * 
	 * <p>
	 * This method is provided for convenience. It is equivalent to the following code: <blockquote> <code>
	 *    getResult().ordinalToCoordinateList(getOrdinal())
	 * </code> </blockquote>
	 * 
	 * @return Coordinates of this Cell
	 */
	List<Integer> getCoordinateList();

	/**
	 * Returns the value of a given property for this Cell.
	 * 
	 * <p>
	 * The list of allowable properties may be obtained by calling {@link org.olap4j.CellSet#getMetaData()} followed by
	 * {@link CellSetMetaData#getCellProperties()}.
	 * </p>
	 * 
	 * <p>
	 * Every cell has certain system properties such as "VALUE" and "FORMAT_STRING" (the full list is described in the
	 * {@link org.olap4j.metadata.Property.StandardCellProperty} enumeration), as well as extra properties defined by
	 * the query.
	 * </p>
	 * 
	 * @param property
	 *            Property whose value to retrieve
	 * 
	 * @return Value of the given property for this Cell; if the property is not set, returns null
	 */
	Object getPropertyValue(Property property);

	/**
	 * Returns whether this cell is empty.
	 * 
	 * @return Whether this cell is empty.
	 */
	boolean isEmpty();

	/**
	 * Returns whether an error occurred while evaluating this cell.
	 * 
	 * @return Whether an error occurred while evaluating this cell.
	 */
	boolean isError();

	/**
	 * Returns whether the value of this cell is NULL.
	 * 
	 * @return Whether the value of this cell is NULL.
	 */
	boolean isNull();

	/**
	 * Returns the value of this cell as a <code>double</code> value.
	 * 
	 * <p>
	 * Not all values can be represented as using the Java <code>double</code>, therefore for some providers,
	 * {@link #getValue()} may return a more accurate result.
	 * 
	 * @return The value of this cell; if the cell is null, the returns <code>0</code>
	 * 
	 * @throws OlapException
	 *             if this cell does not have a numeric value
	 */
	double getDoubleValue() throws OlapException;

	/**
	 * Returns the error message of this Cell, or null if the cell is not in error.
	 * 
	 * <p>
	 * If the cell is an error, the value will be an {@link OlapException}. (This value is returned, not thrown.)
	 * 
	 * @return value of this Cell
	 */
	String getErrorText();

	/**
	 * Returns the value of this Cell.
	 * 
	 * <p>
	 * If the cell is an error, the value will be an {@link OlapException}. (This value is returned, not thrown.)
	 * 
	 * <p>
	 * If the cell has a numeric value, returns an object which implements the {@link Number} interface.
	 * 
	 * @see #getDoubleValue()
	 * 
	 * @return value of this Cell
	 */
	Object getValue();

	/**
	 * Returns the value of this Cell, formatted according to the FORMAT_STRING property and using the numeric
	 * formatting tokens the current locale.
	 * 
	 * <p>
	 * The formatted value is never null. In particular, when the cell contains the MDX NULL value, {@link #getValue()}
	 * will return the Java <code>null</code> value but this method will return the empty string <code>""</code>.
	 * 
	 * @return Formatted value of this Cell
	 */
	String getFormattedValue();

	/**
	 * Drills through from this cell to the underlying fact table data, and returns a {@link java.sql.ResultSet} of the
	 * results.
	 * 
	 * <p>
	 * If drill-through is not possible, returns null.
	 * 
	 * @return result set of the fact rows underlying this Cell
	 * 
	 * @throws OlapException
	 *             if a database error occurs
	 */
	ResultSet drillThrough() throws OlapException;

	/**
	 * Sets the value of a cell.
	 * 
	 * <p>
	 * When this method may be called depends on the provider. But typically, the connection must at least have an
	 * active scenario; see {@link OlapConnection#setScenario(Scenario)}.
	 * 
	 * <p>
	 * The number and type of additional arguments specified in the {@code allocationArgs} parameter depends on the
	 * allocation policy chosen. Some policies, such as {@link AllocationPolicy#EQUAL_ALLOCATION}, do not require any
	 * additional arguments, in which case {@code allocationArgs} may be {@code null}.
	 * 
	 * @param value
	 *            Cell value
	 * @param allocationPolicy
	 *            Allocation policy
	 * @param allocationArgs
	 *            Allocation policy arguments
	 * 
	 * @throws OlapException
	 *             if a database error occurs
	 */
	void setValue(Object value, AllocationPolicy allocationPolicy, Object... allocationArgs) throws OlapException;
}

// End Cell.java
